package com.kuang.demo;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Synchronized和Lock区别
 * 1.Synchronized是内置java关键字，Lock是类
 * 2.Synchronized不能获取锁的状态，Lock可以判断是否获取锁
 * 3.Synchronzied会自动释放锁，Lock需要手动释放锁，要不然就会死锁
 * 4.Synchronzied  线程1 获取锁，线程2会傻傻等，Lock不会等待下去
 * 5.Synchronzid 可重入锁，不可以中断，非公平，Lock，可重入锁，可以判断，非公平（自己设置）
 * 6.Synchronzied 适合锁少量的代码同步问题，Lock适合锁大量的同步代码问题
 */
public class sellTickt2 {
    public static void main(String[] args) {
// 并发：多线程操作同一个资源类, 把资源类丢入线程
        Ticket2 ticket = new Ticket2();
// @FunctionalInterface 函数式接口，jdk1.8 lambda表达式 (参数)->{ 代码 }
        new Thread(()->{
            for (int i = 1; i < 40 ; i++) {
                ticket.sale();
        }
        },"A").start();
        new Thread(()->{
            for (int i = 1; i < 40 ; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 1; i < 40 ; i++) {
                ticket.sale();
            }
        },"C").start();
    }
}
// 资源类 OOP
class Ticket2 {
    // 属性、方法
    private int number = 30;
    Lock lock=new ReentrantLock();//默认不公平锁，如果想要实现公平，可以加true
    // 卖票的方式
// synchronized 本质: 队列，锁
    public  void sale(){
        lock.lock();;
        try{
           // System.out.println(Thread.currentThread().getName());
            if (number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余："+number);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}
